feat(terminal): newline chord as registry data, plus a Key tester in Settings - #522
Conversation
…Settings capabilities.newline replaces choosing the Shift+Enter bytes in the send-key route. Key tester shows the keydown/keypress/keyup a browser reports. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
|
Thanks @opticon454, this moves the Shift+Enter byte choice of the A few things before it goes in:
Smaller things, fine in the same push:
Once 1 to 4 are addressed I'll merge it. |
…tays on line feed - app.js: the shortcut dispatcher returns early for events aimed at a data-raw-keys field, so Ctrl+W / Ctrl+L / Escape / Alt+1 / Ctrl+K pressed in the Key tester no longer kill the session, clear the terminal or close Settings - stock.ts: drop Codex's esc-enter (a line feed works); no stock CLI declares a chord. The esc-enter path is tested through a clis.json override - tests: unused port (3194), Ctrl+Enter asserts no keypress, shortcut-isolation test (verified to fail without the guard) - docs/comments point at capabilities.newline; set-input class, trailing whitespace Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
|
Thanks, all four are fixed in the push above, plus the smaller items. Full gate on the branch: typecheck, lint, format, public assets, catalogue and 8525 tests pass.
Smaller items: the On the |
|
Adding to the
Nothing to do on this PR now. Once #520 merges (and for whichever of #521/#523 lands before this one) I will rebase onto master keeping both sides, re-run the full gate and push. |
…ter cap in their browser tests (#520, #522 review) - Minor: the Key tester "14 lines" test never pressed a key into the tester (the previous test blurred it, so the presses landed on <body> and the cap was never exercised). It now refocuses the field, asserts the focus, clears the log, checks 2 presses accumulate to 6 lines, then 4 presses of another key cap the log at exactly 14 with the oldest 4 lines evicted in order, and the readonly field stays empty. Verified to fail with the cap changed to 20. - Nit: the split-pane invariant implied Ctrl+Enter could use the CLI's declared newline chord. Reworded after checking the send-key route: Ctrl+Enter is always a real 0x0a, Shift+Enter is the declared capabilities.newline chord (0x0a unless the CLI declares another), sent on keydown only. The same imprecision in the auto-named sessions paragraph is corrected too. - Nit: docs/wiki/Settings-Reference.md now lists the Key tester row in the Terminal & Input table. - Nit: test/shift-enter-keypress.browser.test.ts exercised a hand-copied predicate named `shipped`. It now loads the real app from a real WebServer and presses real keys into the handlers terminal-ui.js (app.terminal, recording the real _sendInputAsync send path) and terminal-split.js (a real SplitTerminalPane) attach, recording the send-key POSTs through a fetch wrapper. It asserts no \r reaches either send path for Shift/Ctrl+Enter, exactly one send-key per press for the right session, and that Enter and Alt+Enter are untouched. The old keydown-only gate stays as a labelled reproduction of xterm's keypress behaviour on a bare Terminal. Verified to fail on both panes with the gate narrowed back to keydown. - Nit: the keypress trap is now written down beside the other key-gate rules (Command palette and shortcut registry): xterm runs the custom handler for keydown, keypress and keyup and drops only Ctrl/Alt/Meta keypresses, so a gate on a chord that can carry Shift alone must swallow every event type. The smart-copy keydown-only rule points at it. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
|
Merged and shipped in 1.34.0. Thanks @opticon454! The I applied the remaining review items while landing (52267f8, docs and tests only):
The |
What
Moves "which bytes does Shift+Enter type into this CLI's pane" out of the
send-keyroute and into the CLI registry, and adds a Key tester to Settings.capabilities.newline('line-feed'|'esc-enter', absent = line feed).POST /api/sessions/:id/send-keyreads it forS-Enterinstead of hardcoding0x0a;C-Enteris always a line feed. No stock CLI declares it, so behaviour is unchanged for every CLI today: it is the place to put a CLI whose composer ignores a bare line feed (or a userclis.jsonoverride) instead of amode === 'x'check in the route. It is an enum, not a byte string, so config never carries bytes that get typed into a pane.preventDefaulton keydown (that would suppress the keypress that mattered in fix(terminal): Shift+Enter no longer submits after inserting a newline #520), and keys pressed in it do not trigger app shortcuts: the global shortcut dispatcher skips events aimed at a[data-raw-keys]element.Why
Shift+Enter handling has three layers (browser handler,
send-keybytes, the CLI's own composer). Making the middle one data keeps the registry's no-id-branching rule true, and the Key tester makes the next "Shift+Enter does X on my device" report diagnosable in seconds. Independent of #520 (the keypress fix); they touch different files apart from the test list.Tests
test/cli-newline-capability.test.ts: no stock CLI declares a chord; schema accepts the two values and rejects free-form byte strings; optional.test/routes/session-routes.test.ts: bytes sent to tmux per mode (line feed by default, including codex;ESC CRonly for a CLI that declares it, exercised via aclis.jsonoverride; Ctrl+Enter always a line feed; unknown mode falls back to a line feed).test/key-tester.browser.test.ts(real Chromium): Shift+Enter shows the keypress withcharCode=13, Ctrl+Enter shows none, the field never types, and Ctrl+W / Ctrl+L / Escape / Alt+1 / Ctrl+K pressed in it fire no app shortcut and leave Settings open (verified to fail without the dispatcher guard), while Escape elsewhere still reachescloseAllPanels.🤖 Generated with Claude Code